package cn.org.xiaosheng.okhttp.utils;

import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.naming.ldap.PagedResultsControl;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Objects;

/**
 * @author XiaoSheng
 * @date 2023-11-20
 * @dec 使用OkHttp作为POST请求的工具类底座
 */
@Component
public class PostOkHttpUtils {

    public static final MediaType MEDIA_TYPE_JSON
            = MediaType.parse("application/json;charset=utf-8");

    public static final MediaType MEDIA_TYPE_MULTIPART
            = MediaType.parse("multipart/form-data;charset=utf-8");

    @Resource
    private OkHttpClient okHttpClient;

    /**
     * Post请求（以表单形式提交参数）
     * 通过FormBody.Builder我们可以构建表单参数形式的请求体（类似于HTML中的<form>标签）
     * 键值对将以兼容HTML表单的方式进行编码。
     * @param url
     * @param params
     * @param headers
     * @return
     */
    public JSONObject postOkHttpByFormData(String url,
                                           HashMap<String, Object> params,
                                           HashMap<String, String> headers) {
        Request.Builder reqBuild = new Request.Builder().url(url);
        if (headers != null && !headers.isEmpty()) {
            for (int i = 0; i < headers.size(); i++) {
                reqBuild.addHeader(Objects.toString(headers.keySet().toArray()[i]),
                        Objects.toString(headers.values().toArray()[i]));
            }
        }
        if (params != null && !params.isEmpty()) {
            FormBody.Builder formBody = new FormBody.Builder();
            for (int i = 0; i < params.size(); i++) {
               formBody.add(Objects.toString(params.keySet().toArray()[i]),
                        Objects.toString(params.values().toArray()[i]));
            }
            reqBuild.post(formBody.build());
        } else {
            return null;
        }
        try (Response response = okHttpClient.newCall(reqBuild.build()).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            String respData = response.body().string();
            return (JSONObject) JSONObject.parse(respData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 提交文件 (以表单形式提交参数)
     * @param url
     * @param mediaType
     * @param file
     * @param headers
     * @return
     */
    public JSONObject postOkHttpByFormFile(String url,
                                            MediaType mediaType,
                                            File file,
                                            HashMap<String, String> headers){
        Request.Builder reqBuild = new Request.Builder().url(url);
        if (headers != null && !headers.isEmpty()) {
            for (int i = 0; i < headers.size(); i++) {
                reqBuild.addHeader(Objects.toString(headers.keySet().toArray()[i]),
                        Objects.toString(headers.values().toArray()[i]));
            }
        }
        reqBuild.post(RequestBody.create(mediaType, file));
        try (Response response = okHttpClient.newCall(reqBuild.build()).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            String string = response.body().string();
            return (JSONObject) JSONObject.parse(string);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Post请求（以MultiPart的格式提交文件，分块请求）
     */
    //public JSONObject postOkHttpByMultipartFile(String url,
    //                                            HashMap<String, String> params,
    //                                            File file,
    //                                            HashMap<String, String> headers) {
    //    // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
    //    RequestBody requestBody = new MultipartBody.Builder()
    //            .setType(MultipartBody.FORM)
    //            .addFormDataPart("title", "Square Logo")
    //            .addFormDataPart("image", "logo-square.png",
    //                    RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
    //            .build();
    //
    //    Request request = new Request.Builder()
    //            .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
    //            .url("https://api.imgur.com/3/image")
    //            .post(requestBody)
    //            .build();
    //
    //    try (Response response = client.newCall(request).execute()) {
    //        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
    //
    //        System.out.println(response.body().string());
    //    }
    //}

    /**
     * post请求方式
     * JSON传递格式
     * @param url
     * @param params
     * @param headers
     * @return
     */
    public JSONObject postOkHttpByJson(String url,
                                       HashMap<String, String> params,
                                       HashMap<String, String> headers) {
        return postOkHttp(url, MEDIA_TYPE_JSON, JSONObject.toJSONString(params), headers);
    }

    /**
     * 通过OkHttp,以Post请求方式,请求第三方接口
     * @param url
     * @param mediaType
     * @param params
     * @param headers
     * @return
     */
    public JSONObject postOkHttp(String url,
                                 MediaType mediaType,
                                 String params,
                                 HashMap<String, String> headers){
        Request.Builder reqBuild = new Request.Builder().url(url);
        if (headers != null && !headers.isEmpty()) {
            for (int i = 0; i < headers.size(); i++) {
                reqBuild.addHeader(Objects.toString(headers.keySet().toArray()[i]),
                        Objects.toString(headers.values().toArray()[i]));
            }
        }
        reqBuild.post(RequestBody.create(mediaType, params));
        try (Response response = okHttpClient.newCall(reqBuild.build()).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            String string = response.body().string();
            return (JSONObject) JSONObject.parse(string);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
